#ifndef ARITHMETICOPERATIONMODELGENERATOR_H_JM_20130221
#define ARITHMETICOPERATIONMODELGENERATOR_H_JM_20130221

#include "../generators/ModelGenerator.h"
#include "../generators/Slices.h"
#include "../boxes/DefaultGroupDefinitions.h"

#include "DataInputModelPartGenerator.h"
#include "DataOutputModelPartGenerator.h"

namespace jm4bbx {

	class  ArithmeticOperationModelGenerator  : public ModelGenerator {
	public:
		ArithmeticOperationModelGenerator(
			const int N, // parallelism level
			const std::string& inputBoxName,
			const InputBoxConfiguration& firstInpBoxConf,
			const InputBoxConfiguration& secondInpBoxConf,
			const std::string& operationBoxName,
			const std::string& outputBoxName,
			const std::string& typeName) {
			/// Input
				DataInputModelPartGenerator inGen;
				InputBoxConfiguration confs[2] = {firstInpBoxConf, secondInpBoxConf};
				inGen.addBoxes(this, inputBoxName, confs, 2, N, false, true);
			/// aritmeticka operacia
			BoxDescriptorPtr operation = addBox(operationBoxName, 
				genBoxParam("signal_out", 1), N);
			/// Output
			DataOutputModelPartGenerator oGen;
			oGen.addBoxes(this, outputBoxName, "", N);
			//--------------------------------------------------------------
			//--------------------------------------------------------------
			//-------------------------------------------------------------- 

			inGen.addSlices(this, typeName);


			addSlice(new ForkSlice(inGen.getForkDataBox(0)->getBoxId(), 
				operation->getBoxIds(), N, D_O, D_I, genTypes(typeName, 1)));

			addSlice(new ForkSlice(inGen.getForkDataBox(1)->getBoxId(), 
				operation->getBoxIds(), N, D_O, D_I + 1, genTypes(typeName, 1)));


			addSlice(new MergeSlice(operation->getBoxIds(), 
				oGen.getTimerReportBox()->getBoxId(), N, S_O, S_I));

			addSlice(new ParallelSlice(operation->getBoxIds(), 
				oGen.getOutputBoxes()->getBoxIds(), N, D_O, D_I, 
				genTypes(typeName, 1)));	

			oGen.addSlices(this);
		}

	};

} // namespace jm4bbx


#endif
